Go 1.17 正式发布在即,有何提升?
The following article is from Go开发大全 Author 字符串拼接工程师
【导读】go 1.17 版本即将在 8 月发布,官网介绍了语言层面的三点提升,本文整理了官网1.17版本文档中的三点语言使用层面提升的说明。
1. 切片与数组指针的转换
例如某变量s
类型为[]T
,s
可以被转换成*[N]T
类型。假设a
变量是类型转换的结果,转换时候指定的指针数组的长度在0 <= i < N
范围内转换的结果是&a[i] == &s[i]
的。如果变量s
的len(s)
值小于 N、转换会 panic。
切片类型转换到数组指针时会返回切片底层的数组的指针,切片比转换结果小会引发 panic。
s := make([]byte, 2, 4)
s0 := (*[0]byte)(s) // s0 != nil
s2 := (*[2]byte)(s) // &s2[0] == &s[0]
s4 := (*[4]byte)(s) // panics: len([4]byte) > len(s)
var t []string
t0 := (*[0]string)(t) // t0 == nil
t1 := (*[1]string)(t) // panics: len([1]string) > len(t)
需要注意,切片转换到数组指针是第一个在做类型转换时 panic 的,其他类型转换不触发 panic。认定了类型转换不会触发 panic 的代码分析工具在迭代 go 版本时需要注意这点。
2. unsafe.Add
Add
方法会给 ptr 增加 len 的长度后,返回一个 Pointer(uintptr(ptr) + uintptr(len))
指针。len 参数必须是非负整数或者是无指定类型的常量的非负整数。针对Pointer
的使用规则依然生效。
func Add(ptr Pointer, len IntegerType) Pointer
3. unsafe.Slice
有一个类型是*T
的变量ptr
,unsafe.Slice(ptr, len)
会返回一个切片类型的[]T
,这个切片[]T
的起始位置是 ptr,其 cap 和 len 值都是len
。
Slice(ptr, len)
和下面的写法等价:
(*[len]ArbitraryType)(unsafe.Pointer(ptr))[:]
len
参数必须是整数或者是无指定类型的常量,常量也必须是非负整数。传入的 len 参数是负数和 ptr 是nil
且传参 len 值非 0,这两种情况下会触发 panic。如果 ptr 是nil
,len 值是 0,Slice
也会会返回nil
。
对 unsafe 包的改动,目的是简化符合 unsafe.Pointer 安全规则的代码逻辑,不过这次并没有改 unsafe.Pointer 相关的安全规则。安全规则:https://pkg.go.dev/unsafe@master#Pointer
- EOF -
关注「程序员的那些事」加星标,不错过圈内事
点赞和在看就是最大的支持❤️